Show Code
import geopandas as gpd
import pandas as pdSep 18, 2025
import geopandas as gpd
import pandas as pdHaven’t we already done this?
Yes! So far, we’ve used hvplot, geopandas, & altair to create interactive map-based visualizations.

Pros - Create Leaflet.js maps directly from Python - Combine power of Leaflet.js with the data wrangling ease of Python
Cons - A wrapper for most, but not all of Leaflet’s functionality - Can be difficult to debug and find errors
Check out the Folium docs for more info.
The geopandas .explore() function, which makes interactive choropleth maps, produces Folium maps!
Let’s load the median property assessment data by neighborhood from last lecture’s exercise:
# Load the data from a CSV file into a pandas DataFrame
trash_requests_df = pd.read_csv(
"data/trash_311_requests_2020.csv", # Use the file path relative to the current folder
)
# Remove rows with missing geometry
trash_requests_df = trash_requests_df.dropna(subset=["lat", "lon"])
# Create our GeoDataFrame with geometry column created from lon/lat
trash_requests = gpd.GeoDataFrame(
trash_requests_df,
geometry=gpd.points_from_xy(trash_requests_df["lon"], trash_requests_df["lat"]),
crs="EPSG:4326",
)Load neighborhoods and do the spatial join to associate a neighborhood with each ticket:
# Load the neighborhoods
neighborhoods = gpd.read_file("data/zillow_neighborhoods.geojson")
# Do the spatial join to add the "ZillowName" column
requests_with_hood = gpd.sjoin(
trash_requests,
neighborhoods.to_crs(trash_requests.crs),
predicate="within",
)Group by neighborhood, calculate the number of tickets per neighborhood, and then merge neighborhood geometries.
requests_by_hood = pd.merge(
# GeoDataFrame is left
neighborhoods,
# DataFrame is right: This is the number of tickets per neighborhood
requests_with_hood.groupby("ZillowName", as_index=False).size(),
# Merge column,
on="ZillowName",
).rename(
# Rename size column
columns={"size": "num_tickets"}
)
# Get the area of each geometry in sq. meters
# NOTE: we are converting to EPSG:3857 which has units of meters
area = requests_by_hood.to_crs(epsg=3857).geometry.area
# Normalize by area
requests_by_hood["num_tickets_per_area"] = requests_by_hood["num_tickets"] / area * 1e4requests_by_hood.head()| ZillowName | geometry | num_tickets | num_tickets_per_area | |
|---|---|---|---|---|
| 0 | Academy Gardens | POLYGON ((-74.99851 40.06435, -74.99456 40.061... | 84 | 0.350561 |
| 1 | Allegheny West | POLYGON ((-75.16592 40.00327, -75.16596 40.003... | 330 | 0.646749 |
| 2 | Andorra | POLYGON ((-75.22463 40.06686, -75.22588 40.065... | 83 | 0.212905 |
| 3 | Aston Woodbridge | POLYGON ((-75.0086 40.05369, -75.00861 40.0535... | 110 | 0.486609 |
| 4 | Bartram Village | POLYGON ((-75.20733 39.9335, -75.20733 39.9334... | 35 | 0.155914 |
The .explore() function is a wrapper around Folium/leaflet.js
m = requests_by_hood.explore(column="num_tickets_per_area", tiles="Cartodb positron")
mThe object returned by .explore() a Folium map!
type(m)folium.folium.Map
The .explore() function is a powerful wrapper around folium with a lot of the same functionality of the plot() function in geopandas. In my experience, it is much easier to work with than folium directly. My recommendation is to use the .explore() function when you can.
You can use the same classification schemes to bin your data when using the explore() function. For example:
m = requests_by_hood.explore(
column="num_tickets_per_area",
tiles="Cartodb positron",
scheme="FisherJenks", # NEW: the classification scheme
k=5, # NEW: the number of bins
)
mThe explore() function allows you to specify dictionaries with style keywords for the GeoJSON. The allowed options come directly from the leaflet.js library. Check out the documentation for the .explore() function for more info. You can see the allowed values for GeoJSON on the leaflet documentation.
For example, let’s plot our neighborhood GeoJSON and apply a default style, as well as as a style for when the user hover (highlights) a polygon.
m = neighborhoods.explore(
tiles="Cartodb dark matter",
# NEW: The style dictionary
style_kwds={
"weight": 2,
"color": "lightblue",
"fillOpacity": 0.1,
},
highlight=True, # NEW: turn on highlighting
# NEW: The style dict to apply when hovering
highlight_kwds={
"weight": 2,
"color": "red",
},
)
mYou can also perform styling via functions that take in a GeoJSON feature and return a dictionary of style options. This allows you to style GeoJSON features differently based on the .properties attribute of the GeoJSON feature.
For example:
def my_style_function(feature):
"""Change the style based on whether the number of tickets > 500."""
# Data attributes stored in properties dict
properties = feature["properties"]
# Shared style
style = {"weight": 2, "fillOpacity": 0.8, "color": "white"}
# Change fillColor
if properties["num_tickets"] > 500:
style["fillColor"] = "red"
else:
style["fillColor"] = "lightblue"
# Return style dict
return stylem = requests_by_hood.explore(
tiles="Cartodb dark matter",
style_kwds={"style_function": my_style_function}, # NEW: The style function
)
mWe’ll cover a few more of the key features of Folium today…
Things we’ll cover: 1. Creating a base map with tiles 1. Overlaying GeoJSON features with layer control 1. Examples of Folium plugins
import foliumKey function: folium.Map
Some key ones: - location: the center location of the map - zoom_start: the initial zoom level of the map - tiles: the name of the tile provider
Let’s take a look at the help message:
# folium.Map?# let's center the map on Philadelphia
m = folium.Map(location=[39.99, -75.13], zoom_start=11)
mimport folium
m = folium.Map(location=[39.99, -75.13], zoom_start=6,
tiles="StamenWaterColor",
attr='Map tiles by Stamen Design, CC BY 3.0 — Map data © OpenStreetMap contributors')
mCheck out the xyzservices.providers for all of the available options. You can pass any of these built-in tile providers to Folium.Map() or the .explore() function.
Here is a very useful demo of common tile providers: https://leaflet-extras.github.io/leaflet-providers/preview
import xyzservicesxyzservices.providers
New OneMap | Map data © contributors, Singapore Land Authority
New OneMap | Map data © contributors, Singapore Land Authority
New OneMap | Map data © contributors, Singapore Land Authority
New OneMap | Map data © contributors, Singapore Land Authority
New OneMap | Map data © contributors, Singapore Land AuthorityLet’s try out a couple of examples:
USGS Topo:
m = folium.Map(
location=[39.99, -75.13], zoom_start=11, tiles=xyzservices.providers.USGS.USTopo
)
mEsri National Geographic World Map:
m = folium.Map(
location=[39.99, -75.13],
zoom_start=11,
tiles=xyzservices.providers.Esri.NatGeoWorldMap,
)
mCartoDB Dark Matter:
m = folium.Map(
location=[39.99, -75.13],
zoom_start=11,
tiles=xyzservices.providers.CartoDB.DarkMatter,
)
mThe .explore() function can handle points in addition to polygon geometry objects. And you can layer multiple types of GeoJSON on the same folium map, and add a widget to control which layers are active on the map.
As an example, we’ll keep exploring our trash-related 311 ticket dataset. Let’s take a look at the top 10 neighborhoods in terms of the number of tickets per neighborhood area:
requests_by_hood.sort_values(by="num_tickets_per_area", ascending=False).head(n=10)| ZillowName | geometry | num_tickets | num_tickets_per_area | |
|---|---|---|---|---|
| 57 | Greenwich | POLYGON ((-75.15294 39.92465, -75.15342 39.922... | 214 | 6.781077 |
| 31 | East Passyunk | POLYGON ((-75.16971 39.92442, -75.16835 39.930... | 648 | 6.222775 |
| 86 | Newbold | POLYGON ((-75.16971 39.92442, -75.17023 39.921... | 525 | 5.712863 |
| 72 | Lower Moyamensing | POLYGON ((-75.1566 39.92271, -75.15827 39.9152... | 881 | 5.366825 |
| 5 | Bella Vista | POLYGON ((-75.15865 39.94277, -75.15757 39.942... | 416 | 5.082199 |
| 25 | Dunlap | POLYGON ((-75.22457 39.96492, -75.21995 39.963... | 189 | 4.983522 |
| 139 | West Passyunk | POLYGON ((-75.18528 39.9302, -75.17533 39.9288... | 495 | 4.888462 |
| 108 | Point Breeze | POLYGON ((-75.18495 39.94013, -75.17622 39.939... | 1154 | 4.308334 |
| 103 | Pennsport | POLYGON ((-75.14531 39.93361, -75.14532 39.933... | 447 | 4.062493 |
| 142 | Whitman | POLYGON ((-75.14766 39.91674, -75.14825 39.913... | 476 | 3.983558 |
The Greenwich neighborhood has the highest number of tickets per area, but a relatively low number of overall tickets. Let’s take a look at the tickets in closer detail.
# Extract out the point tickets for Greenwich
greenwich_tickets = requests_with_hood.query("ZillowName == 'Greenwich'")# Get the neighborhood boundary for Greenwich
greenwich_geo = neighborhoods.query("ZillowName == 'Greenwich'")
greenwich_geo.squeeze().geometryIf you are using the .explore() function in geopandas, you if you have an existing Folium map, you can pass it to the explore() function using the m= keyword. See the docs for more info.
# Plot the neighborhood boundary
m = greenwich_geo.explore(
style_kwds={"weight": 4, "color": "black", "fillColor": "none"},
name="Neighborhood boundary",
tiles=xyzservices.providers.CartoDB.Voyager,
)
# Add the individual tickets as circle markers and style them
greenwich_tickets.explore(
m=m, # Add to the existing map!
marker_kwds={"radius": 7, "fill": True, "color": "crimson"},
marker_type="circle_marker", # or 'marker' or 'circle'
name="Tickets",
)
# Hse folium to add layer control
folium.LayerControl().add_to(m)
m # show mapInteresting! There are definitely spatial clusters of 311 tickets, e.g., hot spots. But these tickets are from all of 2020…
Question: I wonder if they were clustered in time as well as space, e.g., a large number of tickets in a short period of time. This could be indicative of a couple bad weeks of trash collections, and a few “power users” putting in lots of repeat 311 tickets to the City if the issue was resolved.
Let’s use the folium/leaflet plugin ecosystem to try to answer this question!
One of leaflet’s strengths: a rich set of open-source plugins
https://leafletjs.com/plugins.html
Many of these are available in Folium! Check out the plugins gallery on the folium documentation for examples.
import folium.pluginsThe folium.plugins.TimestampedGeoJson() object can plot a GeoJSON collection over time, adding a slider to control what time frame is currently shown.
Let’s use this to examine the trends in tickets in Greenwich by month in 2020…
There’s a few things we’ll need to do to prepare:
.to_json() function to convert.# Select only the two columns we need and rename to "time"
ticket_timestamps = (
greenwich_tickets[["requested_datetime", "geometry"]]
.rename(columns={"requested_datetime": "time"})
)# Plot the neighborhood boundary first
m = greenwich_geo.explore(
style_kwds={"weight": 4, "color": "black", "fillColor": "none"},
name="Neighborhood boundary",
tiles=xyzservices.providers.CartoDB.Voyager,
)
# Add the time-stamped GeoJSON
folium.plugins.TimestampedGeoJson(
ticket_timestamps.to_json(), # Convert to GeoJSON
period="P1M", # Show the data in one month intervals
duration="P1M", # Only show points for 1 month and then remove them
auto_play=False, # Don't start playing by default
loop=False, # Loop the animation
max_speed=1, # Max frame speed
loop_button=True, # Show a loop button
transition_time=500, # Time between frames in ms
).add_to(m)
mAh! The summer months, July and August in particular, saw a lot of requests, just as we saw before with the citywide data! By September or October the number of tickets declines, showing that the trash-related problems were a short-term issue.
A brief deep dive, feel free to keep moving!
Styling the markers in this case is much harder to do than when we were working with the .explore() function. We need to add the style dictionary we want as a attribute of each feature’s property dictionary. So we’ll need to convert to a GeoJSON dict, and then manually loop over each feature and add the style we want.
The example below really illustrates how .explore() is often the best option for its ease of use!
The .to_json() function returns a string version of the GeoJSON dict. We can parse it into a Python dict by using the json.loads() function.
import json# This is our GeoJSON points as a dict
geosjon_dict = json.loads(ticket_timestamps.to_json())geosjon_dict{'type': 'FeatureCollection',
'features': [{'id': '842',
'type': 'Feature',
'properties': {'time': '2020-01-06 10:42:43'},
'geometry': {'type': 'Point',
'coordinates': [-75.155657471, 39.923776419]}},
{'id': '1168',
'type': 'Feature',
'properties': {'time': '2020-07-13 21:30:03'},
'geometry': {'type': 'Point',
'coordinates': [-75.153858572, 39.924485692]}},
{'id': '1171',
'type': 'Feature',
'properties': {'time': '2020-03-05 17:35:06'},
'geometry': {'type': 'Point',
'coordinates': [-75.160990158, 39.924627016]}},
{'id': '1172',
'type': 'Feature',
'properties': {'time': '2020-03-05 13:15:21'},
'geometry': {'type': 'Point',
'coordinates': [-75.160990158, 39.924627016]}},
{'id': '1183',
'type': 'Feature',
'properties': {'time': '2020-03-27 14:22:31'},
'geometry': {'type': 'Point',
'coordinates': [-75.155498831, 39.924592881]}},
{'id': '1467',
'type': 'Feature',
'properties': {'time': '2020-01-03 14:18:31'},
'geometry': {'type': 'Point', 'coordinates': [-75.161230033, 39.92354383]}},
{'id': '2389',
'type': 'Feature',
'properties': {'time': '2020-01-24 13:47:48'},
'geometry': {'type': 'Point',
'coordinates': [-75.158356253, 39.923713663]}},
{'id': '2706',
'type': 'Feature',
'properties': {'time': '2020-01-16 13:30:19'},
'geometry': {'type': 'Point',
'coordinates': [-75.160874798, 39.925369821]}},
{'id': '2710',
'type': 'Feature',
'properties': {'time': '2020-01-16 13:59:33'},
'geometry': {'type': 'Point',
'coordinates': [-75.159921056, 39.924371679]}},
{'id': '3025',
'type': 'Feature',
'properties': {'time': '2020-01-28 13:13:58'},
'geometry': {'type': 'Point', 'coordinates': [-75.16083836, 39.925317048]}},
{'id': '3033',
'type': 'Feature',
'properties': {'time': '2020-01-28 13:15:41'},
'geometry': {'type': 'Point',
'coordinates': [-75.159065146, 39.925475093]}},
{'id': '3074',
'type': 'Feature',
'properties': {'time': '2020-01-24 13:49:33'},
'geometry': {'type': 'Point',
'coordinates': [-75.158356253, 39.923713663]}},
{'id': '3119',
'type': 'Feature',
'properties': {'time': '2020-01-25 20:10:35'},
'geometry': {'type': 'Point',
'coordinates': [-75.155601389, 39.924585621]}},
{'id': '3267',
'type': 'Feature',
'properties': {'time': '2020-01-30 11:34:41'},
'geometry': {'type': 'Point',
'coordinates': [-75.155621249, 39.923806944]}},
{'id': '4697',
'type': 'Feature',
'properties': {'time': '2020-02-22 13:35:35'},
'geometry': {'type': 'Point',
'coordinates': [-75.157024208, 39.923213738]}},
{'id': '4715',
'type': 'Feature',
'properties': {'time': '2020-02-21 17:49:57'},
'geometry': {'type': 'Point',
'coordinates': [-75.159090002, 39.923460988]}},
{'id': '4740',
'type': 'Feature',
'properties': {'time': '2020-02-22 13:33:17'},
'geometry': {'type': 'Point', 'coordinates': [-75.15719156, 39.923235233]}},
{'id': '4741',
'type': 'Feature',
'properties': {'time': '2020-02-22 13:34:09'},
'geometry': {'type': 'Point', 'coordinates': [-75.15719156, 39.923235233]}},
{'id': '4742',
'type': 'Feature',
'properties': {'time': '2020-02-24 13:36:54'},
'geometry': {'type': 'Point', 'coordinates': [-75.15719156, 39.923235233]}},
{'id': '4743',
'type': 'Feature',
'properties': {'time': '2020-02-22 13:34:57'},
'geometry': {'type': 'Point',
'coordinates': [-75.157077985, 39.923220645]}},
{'id': '4760',
'type': 'Feature',
'properties': {'time': '2020-02-24 08:13:43'},
'geometry': {'type': 'Point', 'coordinates': [-75.156003433, 39.92385723]}},
{'id': '4990',
'type': 'Feature',
'properties': {'time': '2020-02-08 10:24:59'},
'geometry': {'type': 'Point', 'coordinates': [-75.15301445, 39.92446812]}},
{'id': '5448',
'type': 'Feature',
'properties': {'time': '2020-02-13 13:31:52'},
'geometry': {'type': 'Point',
'coordinates': [-75.156957121, 39.925199659]}},
{'id': '5450',
'type': 'Feature',
'properties': {'time': '2020-02-14 16:32:01'},
'geometry': {'type': 'Point',
'coordinates': [-75.156248603, 39.924521633]}},
{'id': '5451',
'type': 'Feature',
'properties': {'time': '2020-02-14 16:32:02'},
'geometry': {'type': 'Point',
'coordinates': [-75.156248603, 39.924521633]}},
{'id': '5533',
'type': 'Feature',
'properties': {'time': '2020-02-27 13:37:15'},
'geometry': {'type': 'Point',
'coordinates': [-75.156957121, 39.925199659]}},
{'id': '5620',
'type': 'Feature',
'properties': {'time': '2020-08-03 18:19:45'},
'geometry': {'type': 'Point',
'coordinates': [-75.155023658, 39.922932009]}},
{'id': '5812',
'type': 'Feature',
'properties': {'time': '2020-07-13 11:04:22'},
'geometry': {'type': 'Point',
'coordinates': [-75.153809538, 39.924111537]}},
{'id': '5830',
'type': 'Feature',
'properties': {'time': '2020-03-06 08:20:49'},
'geometry': {'type': 'Point',
'coordinates': [-75.157364304, 39.923604389]}},
{'id': '6017',
'type': 'Feature',
'properties': {'time': '2020-02-28 08:47:44'},
'geometry': {'type': 'Point',
'coordinates': [-75.155498831, 39.924592881]}},
{'id': '6345',
'type': 'Feature',
'properties': {'time': '2020-03-06 14:51:03'},
'geometry': {'type': 'Point',
'coordinates': [-75.156902105, 39.923525037]}},
{'id': '6376',
'type': 'Feature',
'properties': {'time': '2020-02-14 15:02:25'},
'geometry': {'type': 'Point',
'coordinates': [-75.154104498, 39.922402842]}},
{'id': '6874',
'type': 'Feature',
'properties': {'time': '2020-04-04 15:27:59'},
'geometry': {'type': 'Point',
'coordinates': [-75.154131141, 39.924046876]}},
{'id': '6930',
'type': 'Feature',
'properties': {'time': '2020-03-19 21:59:44'},
'geometry': {'type': 'Point',
'coordinates': [-75.158978062, 39.923446741]}},
{'id': '7296',
'type': 'Feature',
'properties': {'time': '2020-06-03 08:22:37'},
'geometry': {'type': 'Point',
'coordinates': [-75.157577753, 39.923519941]}},
{'id': '7608',
'type': 'Feature',
'properties': {'time': '2020-03-26 17:15:28'},
'geometry': {'type': 'Point', 'coordinates': [-75.15719156, 39.923235233]}},
{'id': '7609',
'type': 'Feature',
'properties': {'time': '2020-03-27 08:51:24'},
'geometry': {'type': 'Point',
'coordinates': [-75.156438954, 39.924548585]}},
{'id': '7778',
'type': 'Feature',
'properties': {'time': '2020-03-19 22:01:26'},
'geometry': {'type': 'Point', 'coordinates': [-75.159015515, 39.92346995]}},
{'id': '7853',
'type': 'Feature',
'properties': {'time': '2020-03-26 10:51:55'},
'geometry': {'type': 'Point', 'coordinates': [-75.15833899, 39.924966002]}},
{'id': '7856',
'type': 'Feature',
'properties': {'time': '2020-04-04 09:11:40'},
'geometry': {'type': 'Point', 'coordinates': [-75.15403205, 39.924033923]}},
{'id': '7990',
'type': 'Feature',
'properties': {'time': '2020-03-21 10:02:18'},
'geometry': {'type': 'Point', 'coordinates': [-75.15903372, 39.923453825]}},
{'id': '7991',
'type': 'Feature',
'properties': {'time': '2020-03-20 12:13:06'},
'geometry': {'type': 'Point',
'coordinates': [-75.154375886, 39.924079416]}},
{'id': '8026',
'type': 'Feature',
'properties': {'time': '2020-03-17 15:02:06'},
'geometry': {'type': 'Point',
'coordinates': [-75.160026577, 39.924385293]}},
{'id': '8917',
'type': 'Feature',
'properties': {'time': '2020-04-03 14:43:13'},
'geometry': {'type': 'Point',
'coordinates': [-75.159163322, 39.923836319]}},
{'id': '9544',
'type': 'Feature',
'properties': {'time': '2020-04-04 11:11:51'},
'geometry': {'type': 'Point',
'coordinates': [-75.153881217, 39.924382902]}},
{'id': '10058',
'type': 'Feature',
'properties': {'time': '2020-04-05 11:59:07'},
'geometry': {'type': 'Point',
'coordinates': [-75.155827759, 39.924250865]}},
{'id': '10178',
'type': 'Feature',
'properties': {'time': '2020-04-04 10:43:20'},
'geometry': {'type': 'Point',
'coordinates': [-75.154169742, 39.924830538]}},
{'id': '10479',
'type': 'Feature',
'properties': {'time': '2020-04-16 16:44:58'},
'geometry': {'type': 'Point',
'coordinates': [-75.159310994, 39.924926742]}},
{'id': '10480',
'type': 'Feature',
'properties': {'time': '2020-04-16 16:44:56'},
'geometry': {'type': 'Point',
'coordinates': [-75.159310994, 39.924926742]}},
{'id': '10481',
'type': 'Feature',
'properties': {'time': '2020-04-16 19:01:23'},
'geometry': {'type': 'Point',
'coordinates': [-75.157077985, 39.923220645]}},
{'id': '10569',
'type': 'Feature',
'properties': {'time': '2020-04-17 08:04:01'},
'geometry': {'type': 'Point',
'coordinates': [-75.157518089, 39.924466016]}},
{'id': '10590',
'type': 'Feature',
'properties': {'time': '2020-04-16 13:35:01'},
'geometry': {'type': 'Point',
'coordinates': [-75.156965035, 39.923983859]}},
{'id': '10659',
'type': 'Feature',
'properties': {'time': '2020-04-16 09:58:54'},
'geometry': {'type': 'Point',
'coordinates': [-75.156568155, 39.925147821]}},
{'id': '10806',
'type': 'Feature',
'properties': {'time': '2020-04-04 10:05:01'},
'geometry': {'type': 'Point',
'coordinates': [-75.153979574, 39.924395817]}},
{'id': '10807',
'type': 'Feature',
'properties': {'time': '2020-04-04 10:52:05'},
'geometry': {'type': 'Point',
'coordinates': [-75.155332714, 39.924204962]}},
{'id': '10808',
'type': 'Feature',
'properties': {'time': '2020-04-04 10:52:48'},
'geometry': {'type': 'Point',
'coordinates': [-75.155332714, 39.924204962]}},
{'id': '10814',
'type': 'Feature',
'properties': {'time': '2020-04-17 06:32:17'},
'geometry': {'type': 'Point',
'coordinates': [-75.160980797, 39.924670551]}},
{'id': '10815',
'type': 'Feature',
'properties': {'time': '2020-04-17 11:11:30'},
'geometry': {'type': 'Point',
'coordinates': [-75.157124075, 39.925221629]}},
{'id': '11315',
'type': 'Feature',
'properties': {'time': '2020-03-24 11:45:33'},
'geometry': {'type': 'Point',
'coordinates': [-75.160176117, 39.923179212]}},
{'id': '11316',
'type': 'Feature',
'properties': {'time': '2020-03-24 11:45:32'},
'geometry': {'type': 'Point',
'coordinates': [-75.160176117, 39.923179212]}},
{'id': '11601',
'type': 'Feature',
'properties': {'time': '2020-06-02 17:02:50'},
'geometry': {'type': 'Point',
'coordinates': [-75.157557781, 39.923610892]}},
{'id': '12063',
'type': 'Feature',
'properties': {'time': '2020-04-02 19:15:40'},
'geometry': {'type': 'Point', 'coordinates': [-75.15664771, 39.923165179]}},
{'id': '12291',
'type': 'Feature',
'properties': {'time': '2020-04-04 15:29:46'},
'geometry': {'type': 'Point',
'coordinates': [-75.153499985, 39.923944783]}},
{'id': '12292',
'type': 'Feature',
'properties': {'time': '2020-04-04 15:30:15'},
'geometry': {'type': 'Point',
'coordinates': [-75.153499985, 39.923944783]}},
{'id': '12293',
'type': 'Feature',
'properties': {'time': '2020-04-05 10:09:14'},
'geometry': {'type': 'Point',
'coordinates': [-75.153499985, 39.923944783]}},
{'id': '12294',
'type': 'Feature',
'properties': {'time': '2020-04-04 09:12:26'},
'geometry': {'type': 'Point',
'coordinates': [-75.153499985, 39.923944783]}},
{'id': '13161',
'type': 'Feature',
'properties': {'time': '2020-04-04 11:11:22'},
'geometry': {'type': 'Point',
'coordinates': [-75.153881217, 39.924382902]}},
{'id': '13275',
'type': 'Feature',
'properties': {'time': '2020-05-01 10:06:52'},
'geometry': {'type': 'Point', 'coordinates': [-75.15664771, 39.923165179]}},
{'id': '13289',
'type': 'Feature',
'properties': {'time': '2020-05-16 17:59:04'},
'geometry': {'type': 'Point',
'coordinates': [-75.154077824, 39.924408385]}},
{'id': '13511',
'type': 'Feature',
'properties': {'time': '2020-05-01 12:04:47'},
'geometry': {'type': 'Point',
'coordinates': [-75.156837048, 39.923290606]}},
{'id': '13513',
'type': 'Feature',
'properties': {'time': '2020-05-02 15:34:39'},
'geometry': {'type': 'Point',
'coordinates': [-75.155859936, 39.922624416]}},
{'id': '13569',
'type': 'Feature',
'properties': {'time': '2020-04-30 12:09:46'},
'geometry': {'type': 'Point',
'coordinates': [-75.158815108, 39.923444183]}},
{'id': '13925',
'type': 'Feature',
'properties': {'time': '2020-05-15 15:24:57'},
'geometry': {'type': 'Point',
'coordinates': [-75.157056895, 39.923318322]}},
{'id': '13951',
'type': 'Feature',
'properties': {'time': '2020-05-01 15:13:35'},
'geometry': {'type': 'Point',
'coordinates': [-75.157124075, 39.925221629]}},
{'id': '13972',
'type': 'Feature',
'properties': {'time': '2020-05-01 12:24:22'},
'geometry': {'type': 'Point',
'coordinates': [-75.160588898, 39.923794337]}},
{'id': '14093',
'type': 'Feature',
'properties': {'time': '2020-05-01 13:56:05'},
'geometry': {'type': 'Point',
'coordinates': [-75.160812357, 39.925634333]}},
{'id': '14163',
'type': 'Feature',
'properties': {'time': '2020-05-02 08:08:32'},
'geometry': {'type': 'Point',
'coordinates': [-75.160980797, 39.924670551]}},
{'id': '14705',
'type': 'Feature',
'properties': {'time': '2020-06-29 14:26:09'},
'geometry': {'type': 'Point',
'coordinates': [-75.156637474, 39.924372543]}},
{'id': '14707',
'type': 'Feature',
'properties': {'time': '2020-06-29 08:07:47'},
'geometry': {'type': 'Point',
'coordinates': [-75.157315393, 39.923597994]}},
{'id': '15071',
'type': 'Feature',
'properties': {'time': '2020-12-22 10:43:01'},
'geometry': {'type': 'Point',
'coordinates': [-75.158322098, 39.924575654]}},
{'id': '15072',
'type': 'Feature',
'properties': {'time': '2020-12-22 10:42:59'},
'geometry': {'type': 'Point',
'coordinates': [-75.158322098, 39.924575654]}},
{'id': '16753',
'type': 'Feature',
'properties': {'time': '2020-05-20 15:55:59'},
'geometry': {'type': 'Point', 'coordinates': [-75.15548647, 39.923753757]}},
{'id': '16754',
'type': 'Feature',
'properties': {'time': '2020-05-20 15:55:58'},
'geometry': {'type': 'Point', 'coordinates': [-75.15548647, 39.923753757]}},
{'id': '16881',
'type': 'Feature',
'properties': {'time': '2020-05-30 17:02:46'},
'geometry': {'type': 'Point',
'coordinates': [-75.156549668, 39.923130888]}},
{'id': '17122',
'type': 'Feature',
'properties': {'time': '2020-05-16 07:54:11'},
'geometry': {'type': 'Point',
'coordinates': [-75.160812357, 39.925634333]}},
{'id': '17124',
'type': 'Feature',
'properties': {'time': '2020-05-14 22:40:51'},
'geometry': {'type': 'Point',
'coordinates': [-75.160812357, 39.925634333]}},
{'id': '17422',
'type': 'Feature',
'properties': {'time': '2020-07-19 17:25:57'},
'geometry': {'type': 'Point',
'coordinates': [-75.161109322, 39.924099102]}},
{'id': '17588',
'type': 'Feature',
'properties': {'time': '2020-05-15 20:35:31'},
'geometry': {'type': 'Point',
'coordinates': [-75.156914363, 39.923199629]}},
{'id': '18232',
'type': 'Feature',
'properties': {'time': '2020-05-31 19:53:43'},
'geometry': {'type': 'Point',
'coordinates': [-75.153860582, 39.924652984]}},
{'id': '18912',
'type': 'Feature',
'properties': {'time': '2020-05-15 17:12:10'},
'geometry': {'type': 'Point',
'coordinates': [-75.157330149, 39.923996888]}},
{'id': '19708',
'type': 'Feature',
'properties': {'time': '2020-08-17 09:38:15'},
'geometry': {'type': 'Point',
'coordinates': [-75.154962254, 39.922821818]}},
{'id': '19797',
'type': 'Feature',
'properties': {'time': '2020-05-31 10:22:59'},
'geometry': {'type': 'Point',
'coordinates': [-75.157056895, 39.923318322]}},
{'id': '20314',
'type': 'Feature',
'properties': {'time': '2020-07-18 17:50:54'},
'geometry': {'type': 'Point',
'coordinates': [-75.160900125, 39.924068323]}},
{'id': '21421',
'type': 'Feature',
'properties': {'time': '2020-05-17 14:29:59'},
'geometry': {'type': 'Point', 'coordinates': [-75.15548647, 39.923753757]}},
{'id': '21909',
'type': 'Feature',
'properties': {'time': '2020-06-01 09:44:59'},
'geometry': {'type': 'Point',
'coordinates': [-75.158810025, 39.924639382]}},
{'id': '22434',
'type': 'Feature',
'properties': {'time': '2020-06-01 17:48:49'},
'geometry': {'type': 'Point',
'coordinates': [-75.155411307, 39.924089141]}},
{'id': '22469',
'type': 'Feature',
'properties': {'time': '2020-08-17 13:52:37'},
'geometry': {'type': 'Point',
'coordinates': [-75.155234368, 39.924192004]}},
{'id': '22637',
'type': 'Feature',
'properties': {'time': '2020-06-01 09:33:48'},
'geometry': {'type': 'Point',
'coordinates': [-75.160071606, 39.923165322]}},
{'id': '22794',
'type': 'Feature',
'properties': {'time': '2020-06-01 13:31:14'},
'geometry': {'type': 'Point',
'coordinates': [-75.153314987, 39.923059177]}},
{'id': '22867',
'type': 'Feature',
'properties': {'time': '2020-06-01 09:17:34'},
'geometry': {'type': 'Point',
'coordinates': [-75.157170491, 39.923332813]}},
{'id': '23015',
'type': 'Feature',
'properties': {'time': '2020-06-01 09:24:37'},
'geometry': {'type': 'Point',
'coordinates': [-75.160437665, 39.923852075]}},
{'id': '23154',
'type': 'Feature',
'properties': {'time': '2020-06-02 10:16:27'},
'geometry': {'type': 'Point',
'coordinates': [-75.158931238, 39.925043988]}},
{'id': '23155',
'type': 'Feature',
'properties': {'time': '2020-06-02 11:22:30'},
'geometry': {'type': 'Point',
'coordinates': [-75.156902105, 39.923525037]}},
{'id': '23403',
'type': 'Feature',
'properties': {'time': '2020-07-20 23:32:40'},
'geometry': {'type': 'Point',
'coordinates': [-75.155554339, 39.924343244]}},
{'id': '23454',
'type': 'Feature',
'properties': {'time': '2020-07-11 01:55:34'},
'geometry': {'type': 'Point',
'coordinates': [-75.160891854, 39.925284406]}},
{'id': '23662',
'type': 'Feature',
'properties': {'time': '2020-07-30 11:18:50'},
'geometry': {'type': 'Point',
'coordinates': [-75.156549668, 39.923130888]}},
{'id': '23702',
'type': 'Feature',
'properties': {'time': '2020-07-13 17:15:04'},
'geometry': {'type': 'Point',
'coordinates': [-75.153858572, 39.924485692]}},
{'id': '23704',
'type': 'Feature',
'properties': {'time': '2020-07-13 14:16:57'},
'geometry': {'type': 'Point',
'coordinates': [-75.155554339, 39.924343244]}},
{'id': '23862',
'type': 'Feature',
'properties': {'time': '2020-07-12 16:08:55'},
'geometry': {'type': 'Point',
'coordinates': [-75.155736278, 39.924896355]}},
{'id': '23866',
'type': 'Feature',
'properties': {'time': '2020-07-11 12:05:56'},
'geometry': {'type': 'Point',
'coordinates': [-75.155411307, 39.924089141]}},
{'id': '23939',
'type': 'Feature',
'properties': {'time': '2020-07-26 17:38:46'},
'geometry': {'type': 'Point',
'coordinates': [-75.160808254, 39.924695498]}},
{'id': '24877',
'type': 'Feature',
'properties': {'time': '2020-07-13 15:37:52'},
'geometry': {'type': 'Point',
'coordinates': [-75.154963261, 39.924501776]}},
{'id': '24878',
'type': 'Feature',
'properties': {'time': '2020-07-13 15:38:41'},
'geometry': {'type': 'Point',
'coordinates': [-75.154963261, 39.924501776]}},
{'id': '25276',
'type': 'Feature',
'properties': {'time': '2020-07-29 15:19:29'},
'geometry': {'type': 'Point',
'coordinates': [-75.153979411, 39.924270134]}},
{'id': '25469',
'type': 'Feature',
'properties': {'time': '2020-07-12 20:47:51'},
'geometry': {'type': 'Point',
'coordinates': [-75.153907955, 39.924492308]}},
{'id': '25553',
'type': 'Feature',
'properties': {'time': '2020-07-20 09:16:51'},
'geometry': {'type': 'Point', 'coordinates': [-75.16096195, 39.924758202]}},
{'id': '26129',
'type': 'Feature',
'properties': {'time': '2020-08-20 10:15:56'},
'geometry': {'type': 'Point',
'coordinates': [-75.156754525, 39.924263169]}},
{'id': '26172',
'type': 'Feature',
'properties': {'time': '2020-08-19 09:15:17'},
'geometry': {'type': 'Point',
'coordinates': [-75.156966092, 39.924904549]}},
{'id': '26348',
'type': 'Feature',
'properties': {'time': '2020-08-01 14:28:48'},
'geometry': {'type': 'Point',
'coordinates': [-75.153956852, 39.924498958]}},
{'id': '26581',
'type': 'Feature',
'properties': {'time': '2020-08-20 14:26:44'},
'geometry': {'type': 'Point',
'coordinates': [-75.159153753, 39.923583213]}},
{'id': '26925',
'type': 'Feature',
'properties': {'time': '2020-07-31 16:55:06'},
'geometry': {'type': 'Point',
'coordinates': [-75.160083334, 39.925209334]}},
{'id': '27122',
'type': 'Feature',
'properties': {'time': '2020-07-31 10:41:44'},
'geometry': {'type': 'Point',
'coordinates': [-75.158888726, 39.923335123]}},
{'id': '27453',
'type': 'Feature',
'properties': {'time': '2020-08-03 06:44:08'},
'geometry': {'type': 'Point',
'coordinates': [-75.154011991, 39.923907612]}},
{'id': '27463',
'type': 'Feature',
'properties': {'time': '2020-07-31 10:06:15'},
'geometry': {'type': 'Point',
'coordinates': [-75.160083334, 39.925209334]}},
{'id': '27714',
'type': 'Feature',
'properties': {'time': '2020-10-29 15:40:18'},
'geometry': {'type': 'Point',
'coordinates': [-75.160041874, 39.924796408]}},
{'id': '28300',
'type': 'Feature',
'properties': {'time': '2020-06-18 15:35:23'},
'geometry': {'type': 'Point', 'coordinates': [-75.15664771, 39.923165179]}},
{'id': '28534',
'type': 'Feature',
'properties': {'time': '2020-06-26 19:27:38'},
'geometry': {'type': 'Point',
'coordinates': [-75.159143275, 39.923929199]}},
{'id': '28556',
'type': 'Feature',
'properties': {'time': '2020-06-20 15:01:59'},
'geometry': {'type': 'Point', 'coordinates': [-75.15548647, 39.923753757]}},
{'id': '28750',
'type': 'Feature',
'properties': {'time': '2020-06-29 18:08:39'},
'geometry': {'type': 'Point',
'coordinates': [-75.153960556, 39.924130395]}},
{'id': '28751',
'type': 'Feature',
'properties': {'time': '2020-06-29 18:06:23'},
'geometry': {'type': 'Point',
'coordinates': [-75.154207959, 39.923933074]}},
{'id': '28869',
'type': 'Feature',
'properties': {'time': '2020-06-29 18:07:07'},
'geometry': {'type': 'Point',
'coordinates': [-75.154108707, 39.924149572]}},
{'id': '28871',
'type': 'Feature',
'properties': {'time': '2020-06-29 18:09:16'},
'geometry': {'type': 'Point',
'coordinates': [-75.153911239, 39.924124379]}},
{'id': '28872',
'type': 'Feature',
'properties': {'time': '2020-06-29 18:11:10'},
'geometry': {'type': 'Point',
'coordinates': [-75.153759161, 39.924105005]}},
{'id': '28873',
'type': 'Feature',
'properties': {'time': '2020-06-29 18:12:44'},
'geometry': {'type': 'Point',
'coordinates': [-75.154061074, 39.923913234]}},
{'id': '29085',
'type': 'Feature',
'properties': {'time': '2020-06-27 12:21:10'},
'geometry': {'type': 'Point',
'coordinates': [-75.157056895, 39.923318322]}},
{'id': '29131',
'type': 'Feature',
'properties': {'time': '2020-06-29 10:02:02'},
'geometry': {'type': 'Point',
'coordinates': [-75.154837138, 39.923594654]}},
{'id': '29149',
'type': 'Feature',
'properties': {'time': '2020-06-25 20:20:02'},
'geometry': {'type': 'Point',
'coordinates': [-75.156549668, 39.923130888]}},
{'id': '29226',
'type': 'Feature',
'properties': {'time': '2020-06-16 11:59:33'},
'geometry': {'type': 'Point', 'coordinates': [-75.15719156, 39.923235233]}},
{'id': '29252',
'type': 'Feature',
'properties': {'time': '2020-06-29 09:32:09'},
'geometry': {'type': 'Point',
'coordinates': [-75.154717979, 39.924100221]}},
{'id': '29282',
'type': 'Feature',
'properties': {'time': '2020-06-29 07:42:03'},
'geometry': {'type': 'Point',
'coordinates': [-75.154009514, 39.924137084]}},
{'id': '29291',
'type': 'Feature',
'properties': {'time': '2020-06-25 20:19:21'},
'geometry': {'type': 'Point',
'coordinates': [-75.156549668, 39.923130888]}},
{'id': '29465',
'type': 'Feature',
'properties': {'time': '2020-06-29 07:41:25'},
'geometry': {'type': 'Point', 'coordinates': [-75.15405894, 39.924143332]}},
{'id': '29628',
'type': 'Feature',
'properties': {'time': '2020-08-03 17:08:20'},
'geometry': {'type': 'Point',
'coordinates': [-75.153930291, 39.924264078]}},
{'id': '29666',
'type': 'Feature',
'properties': {'time': '2020-06-29 07:40:51'},
'geometry': {'type': 'Point',
'coordinates': [-75.154109783, 39.923920377]}},
{'id': '29667',
'type': 'Feature',
'properties': {'time': '2020-06-29 07:42:36'},
'geometry': {'type': 'Point',
'coordinates': [-75.154108707, 39.924149572]}},
{'id': '29668',
'type': 'Feature',
'properties': {'time': '2020-06-29 07:43:50'},
'geometry': {'type': 'Point',
'coordinates': [-75.153960556, 39.924130395]}},
{'id': '29669',
'type': 'Feature',
'properties': {'time': '2020-06-29 07:44:33'},
'geometry': {'type': 'Point',
'coordinates': [-75.154061074, 39.923913234]}},
{'id': '29670',
'type': 'Feature',
'properties': {'time': '2020-06-29 07:45:07'},
'geometry': {'type': 'Point',
'coordinates': [-75.154011991, 39.923907612]}},
{'id': '29672',
'type': 'Feature',
'properties': {'time': '2020-06-29 07:53:44'},
'geometry': {'type': 'Point',
'coordinates': [-75.154255453, 39.924169321]}},
{'id': '29824',
'type': 'Feature',
'properties': {'time': '2020-06-28 15:25:34'},
'geometry': {'type': 'Point',
'coordinates': [-75.158745882, 39.923531097]}},
{'id': '29847',
'type': 'Feature',
'properties': {'time': '2020-06-29 20:36:14'},
'geometry': {'type': 'Point', 'coordinates': [-75.155753237, 39.92413529]}},
{'id': '29981',
'type': 'Feature',
'properties': {'time': '2020-07-20 16:00:58'},
'geometry': {'type': 'Point',
'coordinates': [-75.155872892, 39.924256778]}},
{'id': '30020',
'type': 'Feature',
'properties': {'time': '2020-06-26 19:53:04'},
'geometry': {'type': 'Point',
'coordinates': [-75.160083334, 39.925209334]}},
{'id': '30175',
'type': 'Feature',
'properties': {'time': '2020-06-27 13:05:14'},
'geometry': {'type': 'Point',
'coordinates': [-75.157112673, 39.923325114]}},
{'id': '30191',
'type': 'Feature',
'properties': {'time': '2020-07-10 11:21:49'},
'geometry': {'type': 'Point', 'coordinates': [-75.15719156, 39.923235233]}},
{'id': '30238',
'type': 'Feature',
'properties': {'time': '2020-06-26 18:41:30'},
'geometry': {'type': 'Point',
'coordinates': [-75.158912273, 39.923456676]}},
{'id': '30416',
'type': 'Feature',
'properties': {'time': '2020-06-28 11:43:04'},
'geometry': {'type': 'Point',
'coordinates': [-75.153956852, 39.924498958]}},
{'id': '30598',
'type': 'Feature',
'properties': {'time': '2020-06-27 09:44:56'},
'geometry': {'type': 'Point',
'coordinates': [-75.157170491, 39.923332813]}},
{'id': '30600',
'type': 'Feature',
'properties': {'time': '2020-06-27 09:46:40'},
'geometry': {'type': 'Point',
'coordinates': [-75.157056895, 39.923318322]}},
{'id': '30603',
'type': 'Feature',
'properties': {'time': '2020-06-27 09:53:50'},
'geometry': {'type': 'Point',
'coordinates': [-75.157330551, 39.923353019]}},
{'id': '30704',
'type': 'Feature',
'properties': {'time': '2020-06-29 18:09:40'},
'geometry': {'type': 'Point',
'coordinates': [-75.153859892, 39.924121205]}},
{'id': '30705',
'type': 'Feature',
'properties': {'time': '2020-06-29 18:05:38'},
'geometry': {'type': 'Point',
'coordinates': [-75.154108707, 39.924149572]}},
{'id': '30706',
'type': 'Feature',
'properties': {'time': '2020-06-29 18:07:32'},
'geometry': {'type': 'Point', 'coordinates': [-75.15405894, 39.924143332]}},
{'id': '30915',
'type': 'Feature',
'properties': {'time': '2020-06-26 13:58:05'},
'geometry': {'type': 'Point',
'coordinates': [-75.156549668, 39.923130888]}},
{'id': '31244',
'type': 'Feature',
'properties': {'time': '2020-06-29 18:10:16'},
'geometry': {'type': 'Point',
'coordinates': [-75.153809538, 39.924111537]}},
{'id': '31282',
'type': 'Feature',
'properties': {'time': '2020-06-29 09:59:02'},
'geometry': {'type': 'Point', 'coordinates': [-75.15573512, 39.922937895]}},
{'id': '31286',
'type': 'Feature',
'properties': {'time': '2020-06-29 12:29:56'},
'geometry': {'type': 'Point',
'coordinates': [-75.154029191, 39.924277681]}},
{'id': '31408',
'type': 'Feature',
'properties': {'time': '2020-07-29 20:48:54'},
'geometry': {'type': 'Point',
'coordinates': [-75.160083334, 39.925209334]}},
{'id': '31541',
'type': 'Feature',
'properties': {'time': '2020-07-29 07:58:37'},
'geometry': {'type': 'Point',
'coordinates': [-75.160083334, 39.925209334]}},
{'id': '31623',
'type': 'Feature',
'properties': {'time': '2020-07-20 09:17:30'},
'geometry': {'type': 'Point',
'coordinates': [-75.160971402, 39.924714243]}},
{'id': '31644',
'type': 'Feature',
'properties': {'time': '2020-08-05 15:20:54'},
'geometry': {'type': 'Point',
'coordinates': [-75.156677739, 39.925162427]}},
{'id': '31944',
'type': 'Feature',
'properties': {'time': '2020-05-31 11:29:36'},
'geometry': {'type': 'Point',
'coordinates': [-75.157269636, 39.924456406]}},
{'id': '32329',
'type': 'Feature',
'properties': {'time': '2020-07-19 17:27:10'},
'geometry': {'type': 'Point',
'coordinates': [-75.161120366, 39.924049232]}},
{'id': '32408',
'type': 'Feature',
'properties': {'time': '2020-07-27 10:24:39'},
'geometry': {'type': 'Point',
'coordinates': [-75.153876231, 39.923134799]}},
{'id': '32820',
'type': 'Feature',
'properties': {'time': '2020-07-18 08:30:10'},
'geometry': {'type': 'Point',
'coordinates': [-75.156549668, 39.923130888]}},
{'id': '33199',
'type': 'Feature',
'properties': {'time': '2020-08-05 15:20:53'},
'geometry': {'type': 'Point',
'coordinates': [-75.156677739, 39.925162427]}},
{'id': '34138',
'type': 'Feature',
'properties': {'time': '2020-07-11 20:12:05'},
'geometry': {'type': 'Point',
'coordinates': [-75.155736278, 39.924896355]}},
{'id': '34438',
'type': 'Feature',
'properties': {'time': '2020-07-26 17:39:54'},
'geometry': {'type': 'Point',
'coordinates': [-75.160818745, 39.924651932]}},
{'id': '34600',
'type': 'Feature',
'properties': {'time': '2020-07-26 00:03:14'},
'geometry': {'type': 'Point',
'coordinates': [-75.157170491, 39.923332813]}},
{'id': '34732',
'type': 'Feature',
'properties': {'time': '2020-07-20 16:35:09'},
'geometry': {'type': 'Point',
'coordinates': [-75.155736278, 39.924896355]}},
{'id': '34734',
'type': 'Feature',
'properties': {'time': '2020-07-20 15:49:50'},
'geometry': {'type': 'Point', 'coordinates': [-75.15403205, 39.924033923]}},
{'id': '37615',
'type': 'Feature',
'properties': {'time': '2020-08-16 10:13:28'},
'geometry': {'type': 'Point',
'coordinates': [-75.160437665, 39.923852075]}},
{'id': '37951',
'type': 'Feature',
'properties': {'time': '2020-09-01 09:40:31'},
'geometry': {'type': 'Point',
'coordinates': [-75.159173895, 39.923490379]}},
{'id': '38344',
'type': 'Feature',
'properties': {'time': '2020-08-13 16:06:44'},
'geometry': {'type': 'Point', 'coordinates': [-75.159102441, 39.92357609]}},
{'id': '38484',
'type': 'Feature',
'properties': {'time': '2020-08-03 06:44:57'},
'geometry': {'type': 'Point',
'coordinates': [-75.153499985, 39.923944783]}},
{'id': '38580',
'type': 'Feature',
'properties': {'time': '2020-08-14 19:06:30'},
'geometry': {'type': 'Point',
'coordinates': [-75.160083334, 39.925209334]}},
{'id': '38582',
'type': 'Feature',
'properties': {'time': '2020-08-15 07:23:03'},
'geometry': {'type': 'Point',
'coordinates': [-75.160261348, 39.923792909]}},
{'id': '39358',
'type': 'Feature',
'properties': {'time': '2020-06-11 23:46:27'},
'geometry': {'type': 'Point', 'coordinates': [-75.16083836, 39.925317048]}},
{'id': '39359',
'type': 'Feature',
'properties': {'time': '2020-06-11 23:46:09'},
'geometry': {'type': 'Point', 'coordinates': [-75.16083836, 39.925317048]}},
{'id': '39507',
'type': 'Feature',
'properties': {'time': '2020-06-05 16:48:01'},
'geometry': {'type': 'Point',
'coordinates': [-75.157589557, 39.923729024]}},
{'id': '39558',
'type': 'Feature',
'properties': {'time': '2020-06-04 08:12:46'},
'geometry': {'type': 'Point',
'coordinates': [-75.156902105, 39.923525037]}},
{'id': '39850',
'type': 'Feature',
'properties': {'time': '2020-06-05 08:15:43'},
'geometry': {'type': 'Point',
'coordinates': [-75.157577753, 39.923519941]}},
{'id': '39939',
'type': 'Feature',
'properties': {'time': '2020-06-11 09:43:29'},
'geometry': {'type': 'Point',
'coordinates': [-75.158323993, 39.924127357]}},
{'id': '40030',
'type': 'Feature',
'properties': {'time': '2020-05-31 13:50:05'},
'geometry': {'type': 'Point',
'coordinates': [-75.159566175, 39.923769955]}},
{'id': '40461',
'type': 'Feature',
'properties': {'time': '2020-10-05 12:23:43'},
'geometry': {'type': 'Point',
'coordinates': [-75.154837138, 39.923594654]}},
{'id': '40536',
'type': 'Feature',
'properties': {'time': '2020-10-02 18:37:33'},
'geometry': {'type': 'Point',
'coordinates': [-75.152994536, 39.924554195]}},
{'id': '41306',
'type': 'Feature',
'properties': {'time': '2020-09-01 09:40:42'},
'geometry': {'type': 'Point',
'coordinates': [-75.159173895, 39.923490379]}},
{'id': '41610',
'type': 'Feature',
'properties': {'time': '2020-09-11 12:05:33'},
'geometry': {'type': 'Point',
'coordinates': [-75.160608015, 39.923808727]}},
{'id': '41671',
'type': 'Feature',
'properties': {'time': '2020-09-03 09:41:39'},
'geometry': {'type': 'Point',
'coordinates': [-75.160608015, 39.923808727]}},
{'id': '41752',
'type': 'Feature',
'properties': {'time': '2020-10-30 08:08:15'},
'geometry': {'type': 'Point',
'coordinates': [-75.156819059, 39.923964673]}},
{'id': '41899',
'type': 'Feature',
'properties': {'time': '2020-10-10 10:02:21'},
'geometry': {'type': 'Point',
'coordinates': [-75.160297641, 39.923631336]}},
{'id': '41948',
'type': 'Feature',
'properties': {'time': '2020-09-11 18:50:12'},
'geometry': {'type': 'Point',
'coordinates': [-75.161039253, 39.924401708]}},
{'id': '43231',
'type': 'Feature',
'properties': {'time': '2020-09-25 15:18:28'},
'geometry': {'type': 'Point',
'coordinates': [-75.153781774, 39.924001494]}},
{'id': '43636',
'type': 'Feature',
'properties': {'time': '2020-10-16 22:34:10'},
'geometry': {'type': 'Point',
'coordinates': [-75.160297641, 39.923631336]}},
{'id': '44666',
'type': 'Feature',
'properties': {'time': '2020-11-14 09:21:53'},
'geometry': {'type': 'Point',
'coordinates': [-75.157170491, 39.923332813]}},
{'id': '45168',
'type': 'Feature',
'properties': {'time': '2020-12-21 10:57:40'},
'geometry': {'type': 'Point',
'coordinates': [-75.155295349, 39.923085778]}},
{'id': '45312',
'type': 'Feature',
'properties': {'time': '2020-12-04 13:48:00'},
'geometry': {'type': 'Point',
'coordinates': [-75.155190902, 39.924166639]}},
{'id': '45341',
'type': 'Feature',
'properties': {'time': '2020-11-05 14:30:34'},
'geometry': {'type': 'Point',
'coordinates': [-75.156278488, 39.924393198]}},
{'id': '45452',
'type': 'Feature',
'properties': {'time': '2020-12-21 09:51:03'},
'geometry': {'type': 'Point',
'coordinates': [-75.157861201, 39.924512434]}},
{'id': '45668',
'type': 'Feature',
'properties': {'time': '2020-11-20 15:43:48'},
'geometry': {'type': 'Point',
'coordinates': [-75.160297641, 39.923631336]}},
{'id': '46048',
'type': 'Feature',
'properties': {'time': '2020-12-04 13:27:54'},
'geometry': {'type': 'Point',
'coordinates': [-75.155190902, 39.924166639]}},
{'id': '47267',
'type': 'Feature',
'properties': {'time': '2020-12-21 11:06:43'},
'geometry': {'type': 'Point',
'coordinates': [-75.159687979, 39.924749294]}},
{'id': '47642',
'type': 'Feature',
'properties': {'time': '2020-12-21 13:42:09'},
'geometry': {'type': 'Point',
'coordinates': [-75.153748975, 39.922764685]}},
{'id': '47643',
'type': 'Feature',
'properties': {'time': '2020-12-21 13:42:08'},
'geometry': {'type': 'Point',
'coordinates': [-75.153748975, 39.922764685]}}]}
Now loop over each feature and add the style:
for feature in geosjon_dict["features"]:
# Use a circle for each icon
feature["properties"]["icon"] = "circle"
# Style the circles
feature["properties"]["style"] = {"radius": 10, "fill": True, "color": "crimson"}# Plot the neighborhood boundary first
m = greenwich_geo.explore(
style_kwds={"weight": 4, "color": "black", "fillColor": "none"},
name="Neighborhood boundary",
tiles=xyzservices.providers.CartoDB.Voyager,
)
# Add the time-stamped GeoJSON
folium.plugins.TimestampedGeoJson(
geosjon_dict, # NEW: use the styled GeoJSON
period="P1M",
duration="P1M",
auto_play=False,
loop=False,
max_speed=1,
loop_button=True,
transition_time=500,
).add_to(m)
mWhat about a heat map visualization of the density of tickets?
# folium.plugins.HeatMap?coords = greenwich_tickets[['lat', 'lon']]# Plot the neighborhood boundary first
m = greenwich_geo.explore(
style_kwds={"weight": 4, "color": "black", "fillColor": "none"},
name="Neighborhood boundary",
tiles=xyzservices.providers.CartoDB.Voyager,
)
# Add heat map coordinates
folium.plugins.HeatMap(coords.values, radius=20).add_to(m)
# Show map
mQuestion: Can we visualize all tickets citywide in 2020 at once?
len(trash_requests)47690
Let’s try the heat map plugin:
# let's center the map on Philadelphia
m = folium.Map(
location=[39.99, -75.13], zoom_start=11, tiles=xyzservices.providers.CartoDB.Voyager
)
# All coords
coords = trash_requests[["lat", "lon"]] # Remember, (lat, lon) order
# Add heat map coordinates
folium.plugins.HeatMap(coords.values, radius=20).add_to(m)
# Show map
m…Not great! There are too many points to properly visualize all of the data at once.
Instead, let’s check out folium.plugins.FastMarkerCluster(). This plugin clusters the data automatically for each zoom level, and can easily handle thousands of points at once without crashing your browser.
# let's center the map on Philadelphia
m = folium.Map(
location=[39.99, -75.13], zoom_start=11, tiles=xyzservices.providers.CartoDB.DarkMatter
)
folium.plugins.FastMarkerCluster(data=coords).add_to(m)
mCheck out the plugins gallery on the folium documentation for the available plugins and examples for each.